package edu.ustb.mis.dm.impl.algorithm;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.poi.ss.usermodel.Workbook;
import edu.ustb.mis.dm.Constants;
import edu.ustb.mis.dm.impl.data.TextInputDataPrepare;
import edu.ustb.mis.dm.interfaces.data.DataPrepare;
import edu.ustb.mis.dm.model.ClusterResult;
import edu.ustb.mis.dm.model.PairModel;
import edu.ustb.mis.dm.model.unit.impl.Instance;
import edu.ustb.mis.dm.util.CombinationUtils;
import edu.ustb.mis.excel.utils.ExcelExporter;

public class ThreshholdCalculator {
	public static void main(final String[] args) throws Exception {
		final ThreshholdCalculator t = new ThreshholdCalculator();
		// t.exec();
		System.out.println(t.exec());
	}

	private final DataPrepare<Instance> dataPrepare = new TextInputDataPrepare(Constants.ZOO_TRANSLATE_NAME);

	private final ClusterResult tmp = new ClusterResult();

	private final Set<PairModel> pairModelSet = new HashSet<PairModel>();

	private double tmpDissimilarity;

	protected List<PairModel> calculateDissimilarity(final Instance i1, final Instance i2) {
		tmp.clearSet();
		tmp.init(i1.getAttributes());
		tmp.contrast(i2.getAttributes());
		//tmpDissimilarity = tmp.diffSize() / (tmp.sameSize()*2);
		tmpDissimilarity = tmp.diffSize() / tmp.allSize();
		final PairModel[] ps = {new PairModel(i1.getClassID(), i2.getClassID(), tmpDissimilarity), new PairModel(i2.getClassID(), i1.getClassID(),
				tmpDissimilarity)};
		return Arrays.asList(ps);
	}

	public double exec() throws Exception {
		final List<Instance> instanceList = dataPrepare.initData();
		final int size = instanceList.size();
		int scope = (int)CombinationUtils.getCnm(size, 2);
		double dissimilarity = 0, tmp_dissimilarity = 0;
		for (int i = 0; i < scope; i++) {
			final List<Instance> pair = CombinationUtils.getValue(instanceList, 2, i);
			final List<PairModel> pms = calculateDissimilarity(pair.get(0), pair.get(1));
			pairModelSet.addAll(calculateDissimilarity(pair.get(0), pair.get(1)));
			tmp_dissimilarity = pms.get(0).getDissimilarity();
			if (!Double.isInfinite(tmp_dissimilarity)) {
				dissimilarity += tmp_dissimilarity;
			} else {
				scope--;
			}
		}
		export(pairModelSet);
		final double means = dissimilarity / scope;
		return means;
	}

	private void export(final Collection<PairModel> excelModelList) throws Exception {
		final OutputStream out = new FileOutputStream(Constants.EXCEL_NAME);
		final ExcelExporter<PairModel> ex = new ExcelExporter<PairModel>();
		final Workbook wb = ex.exportExcel(Constants.EXCEL_TITLE, excelModelList, "2007");
		wb.write(out);
		out.flush();
		out.close();
	}
}
